<template>
  <div>
    <div class="upload-list">
      <span
        v-for="(src, index) in value"
        v-show="Array.isArray(value) && value.length"
        :key="index"
        :class="customClass"
        class="upload-list__item"
      >
        <el-upload
          :key="src"
          v-loading="loadingList[index]"
          class="mutiple-img-uploader"
          :disabled="isLoading"
          action="http://127.0.0.1:8000/simpleUpload"
          :http-request="httpRequest"
          :show-file-list="false"
          :on-success="handleEditSuccess"
          :before-upload="$event => handleChangeImg($event, src, index)"
        >
          <div v-if="src" slot="trigger">
            <img :src="src" class="avatar" @click="handleChange(src, index)">
            <div class="hover-action" />
          </div>
          <i v-else class="el-icon-plus img-uploader-icon" />
          <div class="img-uploader__panel">
            <div v-if="src" class="edit-btn">
              <i class="el-icon-zoom-in" @click.prevent="handleZoonIn(src)" />
              <i
                class="el-icon-delete"
                @click.prevent="handleRemove(src, index)"
              />
            </div>
          </div>
        </el-upload>
      </span>
      <span
        v-show="!numLimit || !Array.isArray(value) || numLimit > value.length"
        v-loading="isLoading"
      >
        <el-upload
          class="mutiple-img-uploader"
          :disabled="isLoading"
          :class="customClass"
          action="http://127.0.0.1:8000/simpleUpload"
          :show-file-list="false"
          :on-success="handleSuccess"
          :http-request="httpRequest"
          :before-upload="validateImg"
        >
          <i class="el-icon-plus img-uploader-icon" />
        </el-upload>
      </span>
    </div>

    <el-dialog
      class="mutiple-img-uploader__dialog"
      :visible.sync="dialogVisible"
      append-to-body
    >
      <el-image
        width="100%"
        :src="dialogImageUrl"
        alt=""
      ><div slot="placeholder" class="image-slot">
        图片加载中
      </div></el-image>
    </el-dialog>
    <div class="el-upload__tip">
      {{ uploadTips }}
    </div>
  </div>
</template>
<script>
/**
 * apk type
 * application/vnd.android.package-archive
 */
import ImgUploadMixin from '../mixins/ImgUploadFn'
import { upload } from 'dependencies/api/index'
import SectionLoadingMixin from 'modules/mixins/section-loading'
export default {
  mixins: [ImgUploadMixin, SectionLoadingMixin],
  props: {
    data: {
      type: [Array, Object],
      default() {
        return {}
      }
    },
    value: {
      type: Array
    },
    prop: {
      type: String,
      default: ''
    },
    // 图片上传数量限制
    numLimit: {
      type: Number,
      default: 0
    }
  },
  data() {
    return {
      dialogImageUrl: '',
      dialogVisible: false,
      disabled: false,
      fileList: [],
      loadingList: [],
      currentFileSrc: '',
      currentFileIndex: -1
    }
  },
  methods: {
    async handleChangeImg(file, src, index) {
      this.$set(this.loadingList, index, true)
      this.currentFileSrc = src
      this.currentFileIndex = index
      return await this.validateImg(file, true)
    },
    async validateImg(file, exchange = false) {
      let errorMsg = ''
      const typeLimit = this.typeLimit(file)
      const numLimit = this.imgUploadMaxLimit(exchange)
      // 类型或数量不对取消后续判断
      if (typeLimit || numLimit) {
        this.$message.error(typeLimit || numLimit)
        if (this.loadingList[this.currentFileIndex]) {
          this.$set(this.loadingList, this.currentFileIndex, false)
        }
        return Promise.reject()
      }

      const sizeLimit = this.sizeLimit(file)
      sizeLimit && (errorMsg += sizeLimit)

      const widthHeightLimit = await this.widthHeightLimit(file)
      widthHeightLimit && (errorMsg += widthHeightLimit)

      // 自定义事件一定要在获取宽高之后
      const validateMsg = this.customLimit(file)
      validateMsg && (errorMsg += validateMsg)

      if (errorMsg) {
        this.$message.error(errorMsg)
        // 格式不同子上传取消loading
        if (this.loadingList[this.currentFileIndex]) {
          this.$set(this.loadingList, this.currentFileIndex, false)
        }
        return Promise.reject()
      }
      return true
    },
    imgUploadMaxLimit(exchange) {
      if (exchange) return ''
      if (
        this.numLimit &&
        Array.isArray(this.value) &&
        this.value.length >= this.numLimit
      ) {
        return `最多只能上传${this.numLimit}张图片!`
      }
      return ''
    },
    handleRemove(src, index) {
      this.$emit(
        'input',
        this.value.filter((path, i) => i !== index)
      )
    },
    handleZoonIn(src) {
      this.dialogImageUrl = src
      this.dialogVisible = true
    },
    handleSuccess(res, file, fileList) {
      if (res.success && res.data) {
        this.$message.success('上传成功!')
        if (Array.isArray(this.value)) {
          this.value.push(res.data)
        } else {
          this.$emit('input', [res.data])
        }
      }
    },
    handleEditSuccess(res, file, fileList) {
      if (res.success && res.data) {
        this.$message.success('上传成功!')
        this.$set(this.loadingList, this.currentFileIndex, false)
        const newSrc = res.data
        this.$emit(
          'input',
          this.value.map((src, index) => {
            if (
              src === this.currentFileSrc &&
              index === this.currentFileIndex
            ) {
              return newSrc
            }
            return src
          })
        )
      }
      this.currentFileUid = undefined
    },
    createImgSimple(raw) {
      return URL.createObjectURL(raw)
    },
    submit() {},
    handleChange(src, index) {
      this.loadingList[index] = true
      this.currentFileSrc = src
      this.currentFileIndex = index
    },
    async httpRequest(data) {
      this.loading()
      const file = new FormData()
      file.append('file', data.file)
      try {
        const res = await upload(file)

        if (res.success) {
          return res
        } else {
          this.handleError()
        }
      } finally {
        this.loaded()
      }
    }
  }
}
</script>
